#include "stdafx.h"
#include <LitExceptions.h>

namespace Lit
{
	Exception::Exception( ExceptionType type, const String &_msg, const String &func_, int _line, const String &_file ) 
	{
		mMessage=_msg;
		mLine=_line; mFile=_file; mFunc= func_; mType= type; 
		_buildFull();
	}
	Exception::Exception( const Exception& rk )
	{
		mMessage = rk.mMessage;
		mLine = rk.mLine;mFile = rk.mFile;mFunc = rk.mFunc;mType = rk.mType;mFull=rk.mFull;
	}
	Exception::~Exception( ){}

	String Exception::location() const{ return String(" in function ")(mFunc)(" at line ")(mLine)(" in file ")(mFile); }
	String Exception::error() const{ return String("Exception(")(String(trExceptionType(mType)))("): ")(mMessage); }
		
	void Exception::_buildFull(){ mFull = String()("Exception(")(String(trExceptionType(mType)))(")\r\n--------------------\r\n")(location())("\r\n\t")(mMessage); }

	const String &Exception::full() const{ return mFull; }

	const char * Exception::what() const{ return mFull.data(); }

	ExceptionType Exception::type() const{ return mType; }
	int Exception::line() const{ return mLine; }
	const String& Exception::file() const{ return mFile; }
	const String& Exception::message() const{ return mMessage; }
	const String& Exception::function() const{ return mFunc; }

	RuntimeError::RuntimeError( ExceptionType type, const String &_msg, const String &func_, int _line, const String &_file ) : Exception( type, _msg, func_, _line, _file ){}
	RuntimeError::RuntimeError( const String &_msg, const String &func_, int _line, const String &_file ) : Exception( EXC_RUNTIME_ERROR, _msg, func_, _line, _file ){}
	RuntimeError::RuntimeError( const RuntimeError & rk  ) : Exception( rk ){}
	RuntimeError::~RuntimeError( ){}

	LogicError::LogicError( ExceptionType type, const String &_msg, const String &func_, int _line, const String &_file ) : Exception( type, _msg, func_, _line, _file ){}
	LogicError::LogicError( const String &_msg, const String &func_, int _line, const String &_file ) : Exception( EXC_LOGIC_ERROR, _msg, func_, _line, _file ){}
	LogicError::LogicError( const LogicError & rk ) : Exception(rk){}
	LogicError::~LogicError( ){}

	NullPointer::NullPointer( const String &msg, const String &func_, int _line, const String &_file ) : RuntimeError( EXC_ITEM_MISSING, ("invalid pointer"+(msg.empty()?String(""):(", "+msg))), func_, _line, _file ){}

	CastError::CastError( const String &varname, const String &from, const String &to, const String &func_, int _line, const String &_file ) : LogicError( EXC_CAST_ERROR, ("cannot convert"+(varname.empty()?String(""):(" variable '"+varname+"'"))+" from "+from+" to "+to), func_, _line, _file ){}

	ImplementationMissing::ImplementationMissing( const String &func_name, const String &func_, int _line, const String &_file ) : LogicError( EXC_ITEM_MISSING, ("Function '"+func_name+"' not yet implemented !"), func_, _line, _file ){}

	IOError::IOError( const String &filename, const String& desc, const String &func_, int _line, const String &_file ) : RuntimeError( EXC_IO_ERROR, ("io_error '"+filename+"': "+desc), func_, _line, _file ){}

	InitialisationError::InitialisationError( const String &msg, const String &func_, int _line, const String &_file ) : LogicError( EXC_INIT_ERROR, ("Cannot initialise lit engine"+(msg.empty()?String(""):(":\r\n--------------------------------------------\r\n\t"+msg))), func_, _line, _file ){}
	ShutdownError::ShutdownError( const String &msg, const String &func_, int _line, const String &_file ) : LogicError( EXC_SHUTDOWN_ERROR, ("Cannot shutdown lit engine"+(msg.empty()?String(""):(":\r\n--------------------------------------------\r\n\t"+msg))), func_, _line, _file ){}

	InvalidPath::InvalidPath( const String &path, bool directory, const String &func_, int _line, const String &_file ) : RuntimeError( EXC_ITEM_MISSING, ("invalid path '"+path+"' for '"+(directory?"directory":"filestream")+"'"), func_, _line, _file ){}

	InvalidParameter::InvalidParameter( const String &param, const String &reason, const String &func_, int _line, const String &_file ) 	: LogicError( EXC_ITEM_MISSING, ("invalid parameter '"+param+"', "+reason), func_, _line, _file ){}
	MissingParameter::MissingParameter( const String &param, const String &func_, int _line, const String &_file ) : LogicError( EXC_ITEM_MISSING, ("missing parameter '"+param+"'"), func_, _line, _file ){}

	ItemMissing::ItemMissing( const String &iitem, const String &item_mgr_name, const String &func_, int _line, const String &_file ) : LogicError( EXC_ITEM_MISSING, item+" missing in Manager['"+item_mgr_name+"']", func_, _line, _file ), item(iitem){}
	ItemDuplicate::ItemDuplicate( const String &iitem, const String &item_mgr_name, const String &func_, int _line, const String &_file ) 	: LogicError( EXC_ITEM_DUPLICATE, item+" already found in Manager['"+item_mgr_name+"']", func_, _line, _file ), item(iitem){}

	FileMissing::FileMissing( const String &ffilename, const String &func, int line, const String &file )	: RuntimeError( EXC_FILE_MISSING, "Missing file '"+filename+"'", func, line, file ), filename( ffilename ){}
	FileDuplicate::FileDuplicate( const String &ffilename, const String &func, int line, const String &file ): RuntimeError( EXC_FILE_DUPLICATE, "File '"+filename+"' already exists, duplicates not allowed", func, line, file ), filename( ffilename ){}
	
	ModuleException::ModuleException( const String &module, const String& error, const String &_func , int _line, const String &_file ) : RuntimeError( EXC_COMPONENT_ERROR, ("Module '"+module+"' caused the following exception:\n"+error), _func, _line, _file ), moduleName( module ){}
	
	ConsoleError::ConsoleError( const String &desc, const String &func, size_t line, const String& file ) : RuntimeError( EXC_CONSOLE_ERROR, String(desc+" "+(!func.empty()?("in function '"+func+"' "):" ") +"at line "+String(std::to_string( line ).c_str())+" in file "+file), func, line, file ){}
	ConsoleTerminateError::ConsoleTerminateError( const String &msg, const String &func, size_t line, const String& file ) : RuntimeError( "/quit "+msg, func, line, file ){}
	StreamError::StreamError( const String &desc, const String &name, const String &func , size_t line, const String &file ) : RuntimeError( "Stream '"+name+"' caused the following error:\r\n\t"+ desc, func, line, file ){}
};